local LogDefine = require("common.LogDefine")
local Log = require("common.Log")
local Lang = require("common.Lang")
--local Util = require("common.Util")
local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local Grid = require("bag.Grid")
local ItemDefine = require("bag.ItemDefine")
local GridLogic = require("bag.GridLogic")
local DropLogic = require("monster.DropLogic")
local Buffer = require("buffer.Buffer")
local ShopHelp = require("shop.ShopHelp")
local MailLogic = require("mail.MailLogicFL")
local Broadcast = require("broadcast.Broadcast")
local VipLogic = require("vip.VipLogic")
local VipDefine = require("vip.VipDefine")
local FamilyHandler = require("family.HandlerL")
local InnerDataManagerFL = require("innerdata.InnerDataManagerFL")
local InnerDataDefine = require("innerdata.Define")
local ArmyRiotL = require("activity.armyRiot.ArmyRiotLogicL")
local RefineHandlerL = require("refine.HandlerL")

local function add_spobj(human, id, cnt, logType)
    onAddItem(human, id, cnt)
    if ItemDefine.spobj.buf and ItemDefine.spobj.buf[id] then
        return Buffer.add(cnt, human, human)
    end
    if ItemDefine.spobj.jingyan[id] then
        return ObjHuman.addExp(human, cnt)
    end
    if ItemDefine.spobj.yinliang[id] then
        return ObjHuman.addYinliang(human, cnt, logType, id, cnt)
    end

    if ItemDefine.spobj.yuanbao[id] then
        local cmd = ItemDefine.spobj.yuanbao[id]
        return ObjHuman.addYuanbao(human, cnt * cmd[3], logType, id, cnt)
    end
    if ItemDefine.spobj.zhangong[id] then
        return ObjHuman.addZhangong(human, cnt, logType)
    end
    if ItemDefine.spobj.weiwang[id] then
        return ObjHuman.addPrestige(human, cnt, logType)
    end
    if ItemDefine.spobj.rongyu[id] then
        return ObjHuman.addRongyu(human, cnt, logType)
    end
    if ItemDefine.spobj.bind_yuanbao[id] then
        return ObjHuman.addBindYuanbao(human, cnt, logType)
    end
    if ItemDefine.spobj.familyexp[id] then
        local nSend2Ldata = {
            type = 10,
            data = {addexp = cnt}
        }
        InnerDataManagerFL.Send2WInnerData(human, InnerDataDefine.INNERDATA_TYPE_FAMILY, nSend2Ldata)
    end
    if ItemDefine.spobj.familycontribution[id] then
        ArmyRiotL.setRiotContribution(human, cnt)
        return FamilyHandler.updateFamilyContribution(human, cnt, true)
    end

    assert(id)
end

function sendCap(human, op)
    local msgRet = Msg.gc.GC_BAG_ADD_CAP
    msgRet.op = op or 0
    msgRet.cap = human.db.bagLen
    Msg.send(msgRet, human.fd)
end

function sendBagList(human, no_always_send)
    Grid.makeList(human, human.db.bag, human.db.bagLen, Msg.gc.GC_BAG_LIST, not no_always_send and Msg.gc.GC_BAG_CLEAR)
end

function sendBagItemChange(human, index, op)
    local msgRet = Msg.gc.GC_BAG_ITEM_CHANGE
    msgRet.op = op or ItemDefine.BAG_NONE
    GridLogic.makeGrid(human.db.bag[index], msgRet.itemData, index, human)
    Msg.send(msgRet, human.fd)
    if RefineHandlerL.isRefineItem(human.db.bag[index].id) or ItemDefine.isGem(human.db.bag[index].id) or human.db.bag[index].id == 0 then
      RefineHandlerL.CG_OPEN_REFINE_WINDOW(human)
    end
end

function sort(human)
    Grid.sort(human.db.bag, human.db.bagLen)
    sendBagList(human)
end

function discard(human, index, logType)
    if not LogDefine.DEFINE[logType] then
        assert()
    end

    if not checkIndex(human, index) then
        return false
    end
    local grid = human.db.bag[index]

    if not grid or grid.id == 0 then
        return false
    end

    local nDiscard = ItemDefine.getValue(grid.id, "canDiscard")
    if nDiscard == 1 then
        send_err(human, ItemDefine.CAN_NOT_DISCARD)
        return false
    end

    Log.writeItemLog(human, grid, -grid.cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["item"])

    if grid.bind == 0 then  --非绑定的道具可以扔在地上
        DropLogic.putItem2Scene(human, grid)
    end
    grid.id = 0
    sendBagItemChange(human, index)
end

function swap(human, srcIndex, tarIndex)
    local bag = human.db.bag
    if not checkIndex(human, srcIndex) or not checkIndex(human, tarIndex) then
        return
    end

    local srcGrid = bag[srcIndex]
    if srcGrid.id == 0 then
        return
    end

    local tarGrid = bag[tarIndex]
    if srcGrid.id == tarGrid.id and (ItemDefine.isItem(srcGrid.id) or ItemDefine.isGem(srcGrid.id) ) and ItemDefine.canAppend(srcGrid.id) and tarGrid.bind == 1 and srcGrid.bind == 0 then
        local cnt = math.min(srcGrid.cnt, ItemDefine.CAP_PER_GRID - tarGrid.cnt)
        tarGrid.cnt = tarGrid.cnt + cnt
        srcGrid.cnt = srcGrid.cnt - cnt
        if srcGrid.cnt <= 0 then
            bag[srcIndex].id = 0
        end
    else
        local ret = GridLogic.swap(human.db.bag, human.db.bagLen, srcIndex, tarIndex)
        if not ret then
            assert()
            return
        end
    end
    sendBagItemChange(human, srcIndex, ItemDefine.BAG_SWAP)
    sendBagItemChange(human, tarIndex, ItemDefine.BAG_SWAP)
end

function send_err(human, err_info)
    local msgErr = Msg.gc.GC_BAG_RESULT
    msgErr.result = err_info
    msgErr.tip = ""
    Msg.send(msgErr, human.fd)
end

--添加背包格子
function addCap(human, cnt)
    if human.db.bagLen >= ItemDefine.BAG_MAX_CAP then
        return send_err(human, ItemDefine.BAG_ADD_CAP_MAX_CNT)
    end
    if human.db.bagLen + cnt > ItemDefine.BAG_MAX_CAP then
        return
    end
    if cnt < 1 then
        return
    end

    local itemCnt = getItemCount(human, ItemDefine.ITEM_ID_ADD_CAP)
    if itemCnt >= cnt then
        delItemsById(human, ItemDefine.ITEM_ID_ADD_CAP, cnt, "add_cap")
    else
        local totalNeedYuanbao = 0
        for i=1, cnt - itemCnt do
            totalNeedYuanbao = totalNeedYuanbao + ItemDefine.ADD_CAP_NEED_YUANBAO
        end

        if not ObjHuman.checkYuanbaoEnough(human, totalNeedYuanbao) then
            return ShopHelp.onNoRMB(human)
        end
        if itemCnt > 0 then
            delItemsById(human, ItemDefine.ITEM_ID_ADD_CAP, itemCnt, "add_cap")
        end
        ObjHuman.decYuanbao(human, totalNeedYuanbao, "add_cap")
    end
    human.db.bagLen = human.db.bagLen + cnt
    sendCap(human, 1)
end
--添加vip背包格子
function addVipCap(human, cnt)
    if human.db.bagLen >= ItemDefine.BAG_MAX_CAP then
        return send_err(human, ItemDefine.BAG_ADD_CAP_MAX_CNT)
    end
    if human.db.bagLen + cnt > ItemDefine.BAG_MAX_CAP then
        human.db.bagLen = ItemDefine.BAG_MAX_CAP
        sendCap(human, 0)
        return
    end
    if cnt < 1 then
        return
    end
    human.db.bagLen = human.db.bagLen + cnt
    sendCap(human, 0)
end

function divide(human, srcIndex, tarIndex, cnt)
    local ret = GridLogic.divide(human.db.bag, human.db.bagLen, srcIndex, tarIndex, cnt)
    if ret then
        sendBagItemChange(human, srcIndex, ItemDefine.BAG_DIVIDE)
        sendBagItemChange(human, tarIndex, ItemDefine.BAG_DIVIDE)
    end
end

function checkCanAddItem(human, id, bind, cnt , lifeTime)
    if bind == 0 or not bind then
        bind = 0
    else
        bind = 1
    end
    if ItemDefine.is_spobj[id] and human._id then
        return true
    end
    if cnt < 1 then
        return
    end
    if not ItemDefine.isValidId(id) then
        return
    end
    local bag = human.db.bag
    local cap = human.db.bagLen
    local capPerGrid = ItemDefine.CAP_PER_GRID
    for i = 0, cap-1 do
        local grid = bag[i]
        if grid.id == 0 or grid.id == id and grid.bind == bind and grid.lifeTime == lifeTime and grid.cnt < capPerGrid and ItemDefine.canAppend(grid.id) then
            if not ItemDefine.canAppend(id) then
                cnt = cnt - 1
            elseif grid.id ~= 0 then
                cnt = cnt - (capPerGrid - grid.cnt)
            else
                cnt = cnt - capPerGrid
            end
            if cnt <= 0 then
                return true
            end
        end
    end
    --	Broadcast.sendBroadcast(human, Lang.MOUSE, Lang.SHOP_ERR_BAG_FULL)
end
function checkCanAddItem2(bag, cap, id, bind, cnt , lifeTime)
    if bind == 0 or not bind then
        bind = 0
    else
        bind = 1
    end
    if cnt < 1 then
        return
    end
    if not ItemDefine.isValidId(id) then
        return
    end
    local capPerGrid = ItemDefine.CAP_PER_GRID
    for i = 0, cap-1 do
        local grid = bag[i]
        if grid.id == 0 or grid.id == id and grid.bind == bind and grid.lifeTime == lifeTime and (grid.cnt < capPerGrid or ItemDefine.is_spobj[id] )and ItemDefine.canAppend(grid.id) then
            if not ItemDefine.canAppend(id) then
                cnt = cnt - 1
            elseif ItemDefine.is_spobj[id] then
                cnt = 0
            elseif grid.id ~= 0 then
                cnt = cnt - (capPerGrid - grid.cnt)
            else
                cnt = cnt - capPerGrid
            end
            if cnt <= 0 then
                return true
            end
        end
    end
end
--item = {[1] = {[1] = id, [2] = cnt, [3] =bind(can nil), [4] = lifeTime(can nil)},
--[2] = {[1] = id, [2] = cnt, [3] =bind(can nil), [4] = lifeTime(can nil)}}
function checkCanAddItemList(human, item, itemLen)
    local bag = human.db.bag
    local cap = human.db.bagLen
    local capPerGrid = ItemDefine.CAP_PER_GRID

    for i = 0, cap-1 do
        local grid = bag[i]
        for kk=1, itemLen do
            if not item[kk][5] then
                local cnt = item[kk][2]
                local bind = item[kk][3]
                if bind == 0 or not bind then
                    bind = 0
                else
                    bind = 1
                end

                if ItemDefine.is_spobj[item[kk][1]] and human._id then
                    item[kk][5] = true
                end
                if cnt < 1 then
                    return
                end
                if not ItemDefine.isValidId(item[kk][1]) then
                    return
                end

                if grid.id == 0 or grid.id == item[kk][1] and grid.bind == bind and grid.lifeTime == item[kk][4]
                    and grid.cnt < capPerGrid and ItemDefine.canAppend(grid.id) and not item[kk][5] then
                    if not ItemDefine.canAppend(item[kk][1]) then
                        cnt = cnt - 1
                    elseif grid.id ~= 0 then
                        cnt = cnt - (capPerGrid - grid.cnt)
                    else
                        cnt = cnt - capPerGrid
                    end
                    if cnt <= 0 then
                        item[kk][5] = true
                        break
                    end
                end
            end
        end
    end
    local canAdd = true
    for i=1, itemLen do
        if not item[i][5] then
            canAdd = false
            break
        end
    end
    for j = 1, itemLen do
        item[j][5] = nil
    end
    return canAdd
end

function addItemToArray(dst, g)
    if not ItemDefine.canAppend(g.id) then
        dst[#dst + 1] = g
        return
    end

    local capPerGrid = ItemDefine.CAP_PER_GRID
    for i =1, #dst do
        local grid = dst[i]
        if grid.id == g.id and grid.bind == g.bind and grid.lifeTime == g.lifeTime and (grid.cnt < capPerGrid  or ItemDefine.is_spobj[g.id]) then
            if ItemDefine.is_spobj[g.id] then
                grid.cnt = grid.cnt + g.cnt
                return
            end
            local cntReal = math.min(capPerGrid - grid.cnt, g.cnt)
            grid.cnt = grid.cnt + cntReal
            g.cnt = g.cnt - cntReal
            if g.cnt <= 0 then
                return
            end
        end
    end
    if g.cnt > 0 then
        dst[#dst + 1] = g
    end
end
function checkDayCntUse(human, itemID, cntOneDay, useCnt)
    local nAldCnt = 0
    local nCntUseData = human.db.item_use_cnt
    if nCntUseData then
        for i = 0, human.db.item_use_cntLen - 1 do
            if nCntUseData[i].itemid == itemID then
                nAldCnt = nCntUseData[i].cnt
            end
        end
    end
    local nVipTime = 0
    if useCnt + nAldCnt > (cntOneDay + nVipTime) then
        return false
    end
    return true
end

function addDayCntUse(human, itemID, useNum)
    local nCntUseData = human.db.item_use_cnt
    if nCntUseData then
        for i = 0, human.db.item_use_cntLen - 1 do
            if nCntUseData[i].itemid == itemID then
                nCntUseData[i].cnt = nCntUseData[i].cnt + useNum
                return
            end
        end
        if human.db.item_use_cntLen < 128 then
            nCntUseData[human.db.item_use_cntLen].itemid = itemID
            nCntUseData[human.db.item_use_cntLen].cnt = useNum
            human.db.item_use_cntLen = human.db.item_use_cntLen + 1
        end
    end
end

function addDayCntUseGroup(human, itemID, useNum, useGroup)
    --处理使用组
    if useGroup > 0 then
        local nUseGroupData = human.db.item_use_group
        for i = 0, human.db.item_use_groupLen - 1 do
            if nUseGroupData[i].group == useGroup then
                nUseGroupData[i].cnt = nUseGroupData[i].cnt + useNum
                return
            end
        end
        if human.db.item_use_groupLen < 128 then
            nUseGroupData[human.db.item_use_groupLen].group = useGroup
            nUseGroupData[human.db.item_use_groupLen].cnt = useNum
            human.db.item_use_groupLen = human.db.item_use_groupLen + 1
        end
    end
end

function checkUseGroupDayCnt(human, itemID, nUseGroup, nUseGroupDayCnt, useCnt)
    local nUseGroupData = human.db.item_use_group
    local nAlgUseCnt = 0
    if nUseGroupData then
        for i = 0, human.db.item_use_groupLen - 1 do
            if nUseGroupData[i].group == nUseGroup then
                nAlgUseCnt = nUseGroupData[i].cnt
            end
        end
    end

    local nVipTime = 0
    if itemID >= 10052 and itemID <= 10060 then
        nVipTime = VipLogic.getVipTimes(human, VipDefine.VIP_PRIVILEGE_USEEXPCARD)
    end
    if nAlgUseCnt + useCnt > (nUseGroupDayCnt + nVipTime) then
        return false
    end
    return true
end

function checkUseCool(human, nCoolGroup, nCoolTime)
    local os_time = os.time()
    local nUseTime = 0
    local nCoolData = human.db.item_use_cool
    if nCoolData then
        for i = 0, human.db.item_use_coolLen - 1 do
            if nCoolData[i].group == nCoolGroup then
                nUseTime = nCoolData[i].usetime
            end
        end
    end

    if nUseTime <= 0 then
        return true
    else
        return (nUseTime <= os_time and os_time - nUseTime >= nCoolTime)
    end
end

function addItemUseCool(human, nCoolGroup, nUseTime)
    local nCoolData = human.db.item_use_cool
    if nCoolData then
        for i = 0, human.db.item_use_coolLen - 1 do
            if nCoolData[i].group == nCoolGroup then
                nCoolData[i].usetime = nUseTime
                return
            end
        end
        if human.db.item_use_coolLen < 128 then
            nCoolData[human.db.item_use_coolLen].group = nCoolGroup
            nCoolData[human.db.item_use_coolLen].usetime = nUseTime
            human.db.item_use_coolLen = human.db.item_use_coolLen + 1
        end
    end
end

pos = pos or {}

function addItem2(bag, cap, id, bind, cnt, qualityOut, lifeTime)
    lifeTime = lifeTime or 0
    if not bind or bind == 0 then
        bind = 0
    else
        bind = 1
    end
    local logGrid
    local capPerGrid = ItemDefine.CAP_PER_GRID
    local posLen = 0
    local grid
    for i = 0, cap-1 do
        grid = bag[i]
        if grid.id == id and grid.bind == bind and grid.cnt < capPerGrid and ItemDefine.canAppend(grid.id) and grid.lifeTime == lifeTime then
            posLen = posLen + 1
            pos[posLen] = i
            local cntReal = math.min(capPerGrid - grid.cnt, cnt)
            grid.cnt = grid.cnt + cntReal
            logGrid = grid
            cnt = cnt - cntReal
            if cnt <= 0 then
                break
            end
        end
    end

    if cnt > 0 then
        for i = 0, cap-1 do
            grid = bag[i]
            if grid.id == 0 then
                posLen = posLen + 1
                pos[posLen] = i
                local cntReal = math.min(capPerGrid, cnt)
                if not ItemDefine.canAppend(id) then
                    cntReal = 1
                end
                bag[i] = Grid.create(grid, id, cntReal, bind, qualityOut, lifeTime)
                logGrid = bag[i]
                if strengthLv then
                    logGrid.data.equip.strengthLv = strengthLv
                end
                cnt = cnt - cntReal
                if cnt <= 0 then
                    break
                end
            end
        end
    end

end
function addItem(human, id, bind, cnt, logType, qualityOut, lifeTime, noSend, strengthLv)
    local realCnt = cnt
    lifeTime = lifeTime or 0
    if not LogDefine.DEFINE[logType] then
        assert()
    end

    if ItemDefine.is_spobj[id] and human.db._id then
        return add_spobj(human, id, cnt, logType)
    end

    if not bind or bind == 0 then
        bind = 0
    else
        bind = 1
    end

    if not checkCanAddItem(human, id, bind, cnt, lifeTime) then
        return
    end

    local logGridCnt = cnt
    local logGrid
    local cap = human.db.bagLen
    local bag = human.db.bag
    local capPerGrid = ItemDefine.CAP_PER_GRID
    local posLen = 0
    local grid
    for i = 0, cap-1 do
        grid = bag[i]
        if grid.id == id and grid.bind == bind and grid.cnt < capPerGrid and ItemDefine.canAppend(grid.id) and grid.lifeTime == lifeTime then
            posLen = posLen + 1
            pos[posLen] = i
            local cntReal = math.min(capPerGrid - grid.cnt, cnt)
            grid.cnt = grid.cnt + cntReal
            logGrid = grid
            cnt = cnt - cntReal
            if cnt <= 0 then
                break
            end
        end
    end

    if cnt > 0 then
        for i = 0, cap-1 do
            grid = bag[i]
            if grid.id == 0 then
                posLen = posLen + 1
                pos[posLen] = i
                local cntReal = math.min(capPerGrid, cnt)
                if not ItemDefine.canAppend(id) then
                    cntReal = 1
                end
                bag[i] = Grid.create(grid, id, cntReal, bind, qualityOut, lifeTime)
                logGrid = bag[i]
                if strengthLv then
                    logGrid.data.equip.strengthLv = strengthLv
                end
                cnt = cnt - cntReal
                if cnt <= 0 then
                    break
                end
            end
        end
    end

    if not noSend then
        local op = nil
        if logType ==  "refine_resolve"then
            op = ItemDefine.BAG_RESOLVE
        elseif logType == "pickup" then
            op = ItemDefine.BAG_PICKUP
        end

        for i = 1 , posLen do
            if human.db._id then
                sendBagItemChange(human, pos[i], op)
            end
        end
    end

    if human.db._id then
        onAddItem(human, id, realCnt, logType)
        Log.writeItemLog(human, logGrid, logGridCnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["item"])
    end
    return true, logGrid, realCnt
end

-- 根据空的下标 增加一个item
function addItemByEmptyIndex(human, index, id, bind, cnt, logType, qualityOut, lifeTime, noSend, strengthenLv)
    if not LogDefine.DEFINE[logType] then
        assert()
    end

    if ItemDefine.is_spobj[id] then
        return add_spobj(human, id, cnt, logType)
    end

    if human.db.bag[index].id ~= 0 then
        assert()
    end

    if not checkIndex(human, index) then
        return false
    end

    if cnt < 1 or cnt > ItemDefine.CAP_PER_GRID then
        return false
    end

    if not ItemDefine.isValidId(id) then
        return false
    end

    local bag = human.db.bag
    Grid.create(bag[index], id, cnt, bind, qualityOut, lifeTime, strengthenLv)

    if not noSend then
        sendBagItemChange(human, index)
    end

    onAddItem(human, id, cnt, logType)

    Log.writeItemLog(human, bag[index], cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["item"])

    return true
end


-- index == nil时 取一个空index
function addItemByGrid(human, index, grid, logType, noSend)
    if not LogDefine.DEFINE[logType] then
        assert()
    end

    if ItemDefine.is_spobj[grid.id] then
        return add_spobj(human, grid.id, grid.cnt, logType)
    end

    if index and human.db.bag[index].id ~= 0 then
        return
    end

    if not index then
        index = getEmptyIndex(human)
        if not index then
            return
        end
    else
        if not checkIndex(human, index) then
            return
        end
    end
    Grid.copy(human.db.bag[index], grid)
    if not noSend then
        local op
        if logType == "pickup" then
            op = ItemDefine.BAG_PICKUP
        end
        sendBagItemChange(human, index, op)
    end

    onAddItem(human, grid.id, grid.cnt, logType)

    Log.writeItemLog(human, grid, grid.cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["item"])

    return true
end


-- 根据下标删除一定数量


function delItemByIndex(human, index, cnt, logType, noSend)
    if not LogDefine.DEFINE[logType] then
        assert()
    end

    if not checkIndex(human, index) then
        return false
    end

    local bag = human.db.bag
    local grid = bag[index]
    local id = grid.id
    local cntLimit = 0
    if ItemDefine.isItem(grid.id) and grid.data.item and grid.data.item.cntLimit then
        cntLimit = grid.data.item.cntLimit
    end

    if cntLimit <= 0 then
        if grid.cnt < cnt then
            return false
        end

        grid.cnt = grid.cnt - cnt

        if grid.cnt < 1 then
            bag[index].id = 0
        end
    else
        --if cnt ~= 1 then
        --    return false
        --end

        if cntLimit < cnt then
            return false
        end

        grid.data.item.cntLimit = grid.data.item.cntLimit - cnt

        if grid.data.item.cntLimit < 1 then
            bag[index].id = 0
        end
    end

    if not noSend then
        sendBagItemChange(human, index)
    end
    if grid.id == 0 then
        grid.id = id
        Log.writeItemLog(human, grid, -cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["item"])
        grid.id = 0
    else
        Log.writeItemLog(human, grid, -cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["item"])
    end
end

-- 根据下标删除一个格子


function delGridByIndex(human, index, logType, noSend)
    if not LogDefine.DEFINE[logType] then
        print("function delGridByIndex logType = " .. logType)
        assert()
    end
    if not checkIndex(human, index) then
        return false
    end

    Log.writeItemLog(human, human.db.bag[index], -human.db.bag[index].cnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["item"])

    human.db.bag[index].id = 0
    if not noSend then
        sendBagItemChange(human, index)
    end
    return true
end

-- 根据id删除多个物品 noBindFirst: true or nil
function delItemsById(human, id, num, logType, noBindFirst, noSend)
    if not LogDefine.DEFINE[logType] then
        assert()
    end

    local posLen = 0
    local bag = human.db.bag
    local logGridNobind
    local logGridNobindCnt = 0
    local logGridBind
    local logGridBindCnt = 0

    local first = noBindFirst and 0 or 1

    for i = 0 , human.db.bagLen-1 do
        if num > 0 then
            local grid = bag[i]
            local minusCnt = 0
            if grid.id == id and grid.bind == first then
                if grid.cnt <= num then
                    num = num - grid.cnt
                    minusCnt = grid.cnt
                    grid.id = 0
                else
                    grid.cnt = grid.cnt - num
                    minusCnt = num
                    num = 0
                end
                posLen = posLen + 1
                pos[posLen] = i

                if grid.bind  == 1 then
                    logGridBindCnt = logGridBindCnt + minusCnt
                    logGridBind = grid
                else
                    logGridNobindCnt = logGridNobindCnt + minusCnt
                    logGridNobind = grid
                end
            end
        else
            break
        end
    end

    if num > 0 then
        first = first == 1 and 0 or 1
        for i = 0 , human.db.bagLen -1 do
            if num > 0 then
                local grid = bag[i]
                local minusCnt = 0
                if grid and grid.id == id and grid.bind == first then
                    if grid.cnt <= num then
                        num = num - grid.cnt
                        minusCnt = grid.cnt
                        grid.id = 0
                    else
                        grid.cnt = grid.cnt - num
                        minusCnt = num
                        num = 0
                    end
                    posLen = posLen + 1
                    pos[posLen] = i

                    if grid.bind then
                        logGridBindCnt = logGridBindCnt + minusCnt
                        logGridBind = grid
                    else
                        logGridNobindCnt = logGridNobindCnt + minusCnt
                        logGridNobind = grid
                    end
                end
            else
                break
            end
        end
    end

    if num > 0 then
        assert(nil, "itemID:"..id)
    end

    local flag
    if logGridBind then

        if logGridBind.id == 0 then
            logGridBind.id = id
            flag = true
        end
        Log.writeItemLog(human, logGridBind, -logGridBindCnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["item"])
        if flag then logGridBind.id = 0 end
    end
    if logGridNobind then
        flag = nil
        if logGridNobind.id == 0 then
            logGridNobind.id = id
            flag = true
        end
        Log.writeItemLog(human, logGridNobind, -logGridNobindCnt, LogDefine.DEFINE[logType] + LogDefine.TYPE["item"])
        if flag then logGridNobind.id = 0 end
    end

    if not noSend then
        for i = 1 , posLen do
            sendBagItemChange(human, pos[i])
        end
    end
end

--根据位置返回格子
function getGridByIndex(human, index)
    if not checkIndex(human, index) then
        return
    end
    return human.db.bag[index]
end

--根据id返回下标
function getIndexById(human, id, search_all)
    local bag = human.db.bag
    local nIndexList = {}
    local nFirstIndex = 0
    for i = 0 , human.db.bagLen-1 do
        local grid = bag[i]
        if grid.id == id then
            nFirstIndex = i
            if not search_all then
                break
            else
                nIndexList[i] = grid
            end
        end
    end
    return nFirstIndex, nIndexList
end

-- 取格子


function getGridById(human, id, bind)
    if not bind or bind == 0 then
        bind = 0
    else
        bind = 1
    end
    local bag = human.db.bag
    for i = 0, human.db.bagLen-1 do
        local grid = bag[i]
        if grid.bind == bind and grid.id == id then
            return grid, i
        end
    end

    for i = 0, human.db.bagLen-1 do
        local grid = bag[i]
        if grid.id == id then
            return grid, i
        end
    end
end

--返回一个空格下标


function getEmptyIndex(human)
    for i = 0, human.db.bagLen-1 do
        local grid = human.db.bag[i]
        if grid.id == 0 then
            return i
        end
    end
end

--背包剩余格数
function getLeftGrids(human)
    local bag = human.db.bag
    local sum = 0
    for i = 0, human.db.bagLen-1 do
        local grid = bag[i]
        if grid.id == 0 then
            sum = sum +1
        end
    end
    return sum
end

-- 获取物品数量
function getItemCount(human, id)
    local bag = human.db.bag
    local sum = 0
    for i = 0 , human.db.bagLen-1 do
        local grid = bag[i]
        if grid.id == id then
            sum = sum + grid.cnt
        end
    end
    return sum
end

-- 获取不绑定的物品数量
function getItemCountNoBind(human, id)
    local bag = human.db.bag
    local sum = 0
    for i = 0 , human.db.bagLen-1 do
        local grid = bag[i]
        if grid.id == id and grid.bind == 0 then
            sum = sum + grid.cnt
        end
    end
    return sum
end

-- 获取绑定的物品数量


function getItemCountBind(human, id)
    local bag = human.db.bag
    local sum = 0
    for i = 0 , human.db.bagLen-1 do
        local grid = bag[i]
        if grid.id == id and grid.bind == 1 then
            sum = sum + grid.cnt
        end
    end
    return sum
end

--检查下标合法
function checkIndex(human, index)
    return GridLogic.checkIndex(human.db.bag, index, human.db.bagLen)
end

--背包物品增加cb
function onAddItem(human, id, cnt)
    if cnt <= 0 then
        cnt = 1
    end
    local msg = string.format("您获得了  %s*%d", ItemDefine.getValue(id, "name"), cnt)
    Broadcast.sendBroadcast(human, Lang.CHAT, msg)
end

function getNeedCap(itemId, itemCnt)
    local cf = ItemDefine.getCf(itemId)
    if cf.command and cf.command[1] == "spobj" then
        return 0
    elseif not cf.command or cf.canAppend == 0 then
        return itemCnt
    elseif cf.command and cf.command[1] ~= "spobj" then
        return math.ceil(itemCnt / 100)
    else
        assert(nil, itemId)
    end
end


-- 发奖励 规则是如果在线并且背包空间足够并且在活动地图 那么直接奖励道具放背包 其他情况都发邮件
function sendReward(uuid, grids, title, content, logtype)
    local human = ObjHuman.onlineUuid[uuid]
    if human then
        local sum = 0
        for i = 1, #grids do
            if not ItemDefine.is_spobj[grids[i].id] then
                sum = sum + 1
            end
        end
        if getLeftGrids(human) < sum then
            human = nil
        end
    end
    if human then
        for i = 1, #grids do
            if ItemDefine.isEquip(grids[i].id) then
                addItemByGrid(human, nil, grids[i], logtype)
            else
                addItem(human, grids[i].id, grids[i].bind, grids[i].cnt, logtype)
            end
        end
    else
        MailLogic.CreateNewMailForUser(uuid, title, content, grids)
    end
end

